package scantask.client.presentationLayer;

import gov.nasa.worldwind.WorldWindow;
import gov.nasa.worldwind.layers.AirspaceLayer;
import gov.nasa.worldwind.render.Material;
import gov.nasa.worldwind.render.airspaces.Airspace;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import java.util.Map.Entry;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

import scantask.containers.PestsLevelsSigelton;

public class ShowHidePanel extends JPanel{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	// The world window of NASA.
	final private WorldWindow _wwd;
	
	// Layers for shapes.
	private Map<String, AirspaceLayer> _layers;
	
	private Map<String, String> _layersNames;
	
	// Enabled layers list.
	private JList _enabled;
	
	// Enabled vector.
	private Vector<String> _enabledVec;
	
	// Disabled layers list.
	private JList _disabled;
	
	// Disabled vector.
	private Vector<String> _disabledVec;
	
	// The last pest layer shown.
	private AirspaceLayer _lastPestLayer;
	
	// Color of last pest layer.
	private Material _colorOfLastLayer;
	
	public ShowHidePanel(WorldWindow wwd) {
		
		super();
		this.setLayout(null);
		this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
	
		this._wwd = wwd;
		this._layers = null;
		this._layersNames = null;
		this._lastPestLayer = null;
		this._colorOfLastLayer = null;
		
		JLabel showLabel = new JLabel();
		showLabel.setText("Shown:");
		showLabel.setBounds(10, 10, 80, 25);
        this.add(showLabel);
        
        JLabel hideLabel = new JLabel();
        hideLabel.setText("Hidden:");
        hideLabel.setBounds(155, 10, 80, 25);
        this.add(hideLabel);
        
        this._enabledVec = new Vector<String>();
        this._disabledVec = new Vector<String>();
        
        this._enabled = new JList();
        this._enabled.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        this._enabled.setLayoutOrientation(JList.VERTICAL);
        JScrollPane enabledScroll = new JScrollPane(this._enabled);
        enabledScroll.setBounds(10, 45, 75, 150);
        this.add(enabledScroll);
        
        this._disabled = new JList();
        this._disabled.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        this._disabled.setLayoutOrientation(JList.VERTICAL);
        JScrollPane disabledScroll = new JScrollPane(this._disabled);
        disabledScroll.setBounds(155, 45, 75, 150);
        this.add(disabledScroll);
        
        JButton hide = new JButton(">");
        hide.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				boolean onePestLayer = false;
				if (ShowHidePanel.this.countShownPestsLayer() == 1){
					onePestLayer = true;
				}
				Object[] values = ShowHidePanel.this._enabled.getSelectedValues();
				Vector<String> valuesVec = new Vector<String>();
				for(int i = 0; i< values.length; i++){
					valuesVec.add((String)values[i]);
				}
				ShowHidePanel.this._disabledVec.addAll(valuesVec);
				ShowHidePanel.this._disabled.setListData(ShowHidePanel.this._disabledVec);
				ShowHidePanel.this._enabledVec.removeAll(valuesVec);
				ShowHidePanel.this._enabled.setListData(ShowHidePanel.this._enabledVec);
				for (int i = 0; i<values.length; i++){
					ShowHidePanel.this._layers.get(
							ShowHidePanel.this._layersNames.get(values[i])).setEnabled(false);
				}
				if( (ShowHidePanel.this.countShownPestsLayer() == 0)
						&& (onePestLayer) ){
					ShowHidePanel.this.paintOriginalColors();
				}
				if(ShowHidePanel.this.countShownPestsLayer() == 1){
					ShowHidePanel.this.findLastPestLayerShown();
					ShowHidePanel.this.paintLastPestLayerRYG();
				}
				ShowHidePanel.this.update();
			}
        	
        });
        hide.setBounds(95, 90, 50, 25);
        hide.setToolTipText("Hide");
        this.add(hide);
        
        JButton show = new JButton("<");
        show.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				boolean onePestLayer = false;
				boolean noPestLayer = false;
				if (ShowHidePanel.this.countShownPestsLayer() == 1){
					onePestLayer = true;
				}
				else if (ShowHidePanel.this.countShownPestsLayer() == 0){
					noPestLayer = true;
				}
				Object[] values = ShowHidePanel.this._disabled.getSelectedValues();
				Vector<String> valuesVec = new Vector<String>();
				for(int i = 0; i< values.length; i++){
					valuesVec.add((String)values[i]);
				}
				ShowHidePanel.this._enabledVec.addAll(valuesVec);
				ShowHidePanel.this._enabled.setListData(ShowHidePanel.this._enabledVec);
				ShowHidePanel.this._disabledVec.removeAll(valuesVec);
				ShowHidePanel.this._disabled.setListData(ShowHidePanel.this._disabledVec);
				for (int i = 0; i<values.length; i++){
					ShowHidePanel.this._layers.get(
							ShowHidePanel.this._layersNames.get(values[i])).setEnabled(true);
				}
				if( (ShowHidePanel.this.countShownPestsLayer() >= 2) && (onePestLayer) ){
					ShowHidePanel.this.paintOriginalColors();
				}
				else if ( (ShowHidePanel.this.countShownPestsLayer() == 1)
						&& (noPestLayer) ){
					ShowHidePanel.this.findLastPestLayerShown();
					ShowHidePanel.this.paintLastPestLayerRYG();
				}
				ShowHidePanel.this.update();
			}
        	
        });
        show.setBounds(95, 125, 50, 25);
        show.setToolTipText("Show");
        this.add(show);
        
        JButton showAll = new JButton("<<");
        showAll.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				boolean onePestLayer = false;
				boolean noPestLayer = false;
				if (ShowHidePanel.this.countShownPestsLayer() == 1){
					onePestLayer = true;
				}
				else if (ShowHidePanel.this.countShownPestsLayer() == 0){
					noPestLayer = true;
				}
				Iterator<Entry<String, AirspaceLayer>> iter = 
						ShowHidePanel.this._layers.entrySet().iterator();
				Entry<String, AirspaceLayer> entry;
				while(iter.hasNext()){
					entry = iter.next();
					entry.getValue().setEnabled(true);
				}
				ShowHidePanel.this._enabledVec.addAll(ShowHidePanel.this._disabledVec);
				ShowHidePanel.this._enabled.setListData(ShowHidePanel.this._enabledVec);
				ShowHidePanel.this._disabledVec.removeAllElements();
				ShowHidePanel.this._disabled.setListData(ShowHidePanel.this._disabledVec);
				if( (ShowHidePanel.this.countShownPestsLayer() >= 2)
						&& (onePestLayer) ){
					ShowHidePanel.this.paintOriginalColors();
				}
				else if ( (ShowHidePanel.this.countShownPestsLayer() == 1)
						&& (noPestLayer) ){
					ShowHidePanel.this.findLastPestLayerShown();
					ShowHidePanel.this.paintLastPestLayerRYG();
				}
				ShowHidePanel.this.update();
			}
        	
        });
        showAll.setBounds(95, 160, 50, 25);
        showAll.setToolTipText("Show all");
        this.add(showAll);
        
        JButton hideAll = new JButton(">>");
        hideAll.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				boolean onePestLayer = false;
				if (ShowHidePanel.this.countShownPestsLayer() == 1){
					onePestLayer = true;
				}
				Iterator<Entry<String, AirspaceLayer>> iter = 
						ShowHidePanel.this._layers.entrySet().iterator();
				Entry<String, AirspaceLayer> entry;
				while(iter.hasNext()){
					entry = iter.next();
					entry.getValue().setEnabled(false);
				}
				ShowHidePanel.this._disabledVec.addAll(ShowHidePanel.this._enabledVec);
				ShowHidePanel.this._disabled.setListData(ShowHidePanel.this._disabledVec);
				ShowHidePanel.this._enabledVec.removeAllElements();
				ShowHidePanel.this._enabled.setListData(ShowHidePanel.this._enabledVec);
				if( (ShowHidePanel.this.countShownPestsLayer() == 0)
						&& (onePestLayer) ){
					ShowHidePanel.this.paintOriginalColors();
				}
				ShowHidePanel.this.update();
			}
        	
        });
        hideAll.setBounds(95, 55, 50, 25);
        hideAll.setToolTipText("Hide all");
        this.add(hideAll);
        
	}
	
	public void updatePanel(Map<String, AirspaceLayer> layers){
		this._layers = layers;
		this._layersNames = new HashMap<String, String>();
		this._enabled.removeAll();
		this._disabled.removeAll();
		this._enabledVec.removeAllElements();
		this._disabledVec.removeAllElements();
		
		Iterator<Entry<String, AirspaceLayer>> iter = layers.entrySet().iterator();
		while(iter.hasNext()){
			String shortName = "";
			Entry<String, AirspaceLayer> entry = iter.next();
			String[] strArray = entry.getKey().split("\t");
			if(strArray.length > 2){
				shortName = strArray[2];
				if(!strArray[3].contains("Not")){
					shortName += " Interpolated";
				}
			}
			else if(strArray.length == 2){
				shortName = strArray[1];
			}
			else{
				shortName = entry.getKey();
			}
			this._layersNames.put(shortName, entry.getKey());
			this._enabledVec.add(shortName);
		}
		this._enabled.setListData(this._enabledVec);
		if(ShowHidePanel.this.countShownPestsLayer() == 1){
			ShowHidePanel.this.findLastPestLayerShown();
			ShowHidePanel.this.paintLastPestLayerRYG();
		}
		ShowHidePanel.this.update();
	}
	
	public void removeLayers(){
		Iterator<Entry<String, AirspaceLayer>> iter
						= this._layers.entrySet().iterator();
		while(iter.hasNext()){
			iter.next().getValue().removeAllAirspaces();
		}
		this._layers.clear();
	}
	
	private int countShownPestsLayer(){
		int count = 0;
		Iterator<Entry<String, AirspaceLayer>> iter
									= this._layers.entrySet().iterator();
		while(iter.hasNext()){
			Entry<String, AirspaceLayer> curr = iter.next();
			if(curr.getKey().contains("Pest")){
				if(curr.getValue().isEnabled()){
					count++;
				}
			}
		}
		return count;
	}
	
	private void findLastPestLayerShown(){
		Iterator<Entry<String, AirspaceLayer>> iter
									= this._layers.entrySet().iterator();
		while(iter.hasNext()){
			Entry<String, AirspaceLayer> curr = iter.next();
			if(curr.getKey().contains("Pest")){
				if(curr.getValue().isEnabled()){
					this._lastPestLayer = curr.getValue();
					this._colorOfLastLayer = curr.getValue().getAirspaces().
								iterator().next().getAttributes().getMaterial();
					return;
				}
			}
		}
	}
	
	private void paintLastPestLayerRYG(){
		if (this._lastPestLayer == null){
			return;
		}
		Iterator<Airspace> iter = this._lastPestLayer.getAirspaces().iterator();
		while(iter.hasNext()){
			Airspace a = iter.next();
			double up = a.getAltitudes()[1];
			String level = PestsLevelsSigelton.getPestLevel(
					(up / (FunctionalityPanel.DEFAULT_FACTOR + 1)));
			if(level.equals("low")){
				a.getAttributes().setMaterial(new Material(Color.GREEN));
			}
			else if(level.equals("medium")){
				a.getAttributes().setMaterial(new Material(Color.YELLOW));
			}
			else if(level.equals("high")){
				a.getAttributes().setMaterial(new Material(Color.RED));
			}
		}
	}
	
	private void paintOriginalColors(){
		if (this._lastPestLayer == null){
			return;
		}
		Iterator<Airspace> iter = this._lastPestLayer.getAirspaces().iterator();
		while(iter.hasNext()){
			Airspace a = iter.next();
			a.getAttributes().setMaterial(this._colorOfLastLayer);
		}
	}
	
	// Update Globe.
    private void update()
    {
        this._wwd.redraw();
    }

}
